package cn.edu.nuc.chat.server;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;

import cn.edu.nuc.chat.util.Token;

public class Talk implements Runnable {
	
	//与单个客户端的链接socket
	private Socket client = null;
	//存储当前所有在线用户列表
	private static Map<String, Socket> clients = new HashMap<>();
	
	private BufferedReader reader = null;
    private PrintWriter writer = null;
    
	public Talk(Socket client){
		this.client = client;
	}

	@Override
	public void run() {
		if( this.client == null || this.client.isClosed() ){
			return;
		}
		
		try {
			reader = new BufferedReader(new InputStreamReader(client.getInputStream()));
            writer = new PrintWriter(client.getOutputStream(), true);
			exit:while( true ){
				String msg = reader.readLine();
				if( msg == null ){
					break;
				}
				//msg:uuid:昵称:消息
				//String [] str = msg.split(":");
				//login:sdf879sdfs-sdfs8s-sdfs7k-skysdf:张三
				StringTokenizer st = new StringTokenizer(msg, Token.DELIM);
				String command = st.nextToken();
				String uuid = st.nextToken().trim();
				switch( command ){
					case "login":
						//通知所有线上用户
						broadcast( msg + Token.DELIM + st.nextToken()/*昵称*/ );
						//添加到在线列表
						clients.put(uuid, client);
						break;
					case "msg":
						StringBuilder sb = new StringBuilder("msg:");
						sb.append(st.nextToken() ); 			//发消息方的uuid
						sb.append( Token.DELIM );
						sb.append(st.nextToken()); 	//昵称
						sb.append( Token.DELIM );
						sb.append(st.nextToken());	//消息内容
						this.send( clients.get(uuid), sb.toString() );
						break;
					case "logout":
						//通知所有线上用户
						broadcast( msg );
						
						this.send( clients.get(uuid), "bye" );
						//移除
						clients.remove(uuid);
						break exit;
				}
			}
		} catch ( IOException e){
			System.out.println("链接已断开");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if( writer != null )writer.close();
				if( reader != null )reader.close(); 
				if( client != null && client.isConnected() ) client.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

	}
	
	/**
	 * 向所有在线用户列表发送消息
	 * @param msg
	 */
	private void broadcast(String msg){
		Set<Map.Entry<String, Socket>> entries = clients.entrySet();
		for(Map.Entry<String, Socket> entry : entries){
			send(entry.getValue(), msg);
		}
	}
	
	private void send(Socket client, String msg){
		try {
			new PrintWriter(client.getOutputStream(), true).println(msg);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public static  Map<String, Socket> getClients(){
		return clients;
	}

}
